/*****************************************************************************
 *   Copyright 2005 Tim A Wang
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 ****************************************************************************/
package com.jb.web.application.configuration;

import com.jb.framework.DataSourceManager;
import com.jb.framework.database.UpdateDBCommand;
import com.jb.util.ClassUtil;
import com.jb.web.context.WebContext;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class DBConfig extends ConfigBean {
    private Log log = LogFactory.getLog(getClass().getName());

    private String dataSourceName = "jbDB";
    private String databaseDriverName = "com.mysql.jdbc.Driver";
    private String hostName = "localhost";
    private String password = "welcome";
    private String schema = "jb";
    private String schemaFactory = "com.jb.application.configuration.CreateSchema";
    private String userName = "root";
    private boolean useDataSource;

    public void setDataSourceName(String dataSourceName) {
        this.dataSourceName = dataSourceName;
    }

    public String getDataSourceName() {
        return dataSourceName;
    }

    public void setDriverName(String databaseDriverName) {
        this.databaseDriverName = databaseDriverName;
    }

    public String getDriverName() {
        return databaseDriverName;
    }

    public void setHostName(String hostName) {
        this.hostName = hostName;
        if(this.hostName!=null&&this.hostName.indexOf("derby")!=-1)
            System.getProperties().put("derby.system.home", Config.getInstance().getApplTop());
    }

    public String getHostName() {
        return hostName;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }

    public void setSchema(String schema) {
        this.schema = schema;
    }

    public String getSchema() {
        return schema;
    }

    public void setSchemaFactory(String schemaFactory) {
        this.schemaFactory = schemaFactory;
    }

    public String getSchemaFactory() {
        return schemaFactory;
    }

    public String getUrl() {
        return hostName;
    }

    public void setUseDataSource(boolean useDataSource) {
        this.useDataSource = useDataSource;
    }

    public boolean isUseDataSource() {
        return useDataSource;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserName() {
        return userName;
    }

    public void createDefault(WebContext pCtx) {
        Connection connection = null;
        try {
            connection = DataSourceManager.getConnection(this);
            createSchema(connection);
        } catch (Exception e) {
            if(log.isErrorEnabled())
                log.error(this, e);
        } finally {
            DataSourceManager.releaseConnection(this, connection);
        }
    }

    //this is db flavor specific decration
    //this basical decorate connection, includng personalize the connection
    public void decorate(Connection conn) throws SQLException {

        try {
            if("MySQL".equals(conn.getMetaData().getDatabaseProductName()))
            {
                String useStmt = "use " + schema;
                UpdateDBCommand.executeStmt(useStmt, conn);
            }
        } catch (SQLException e) {
            if(log.isErrorEnabled())
                log.error(this, e);
        }
    }
    private CreateSchema createSchema() {
        return (CreateSchema)ClassUtil.createInstance(schemaFactory);
    }
    
    private void createSchema(Connection conn) throws SQLException {
        try {
            String dropdata = "drop database " + schema;
            UpdateDBCommand.executeStmt(dropdata, conn);
        } catch (Exception e) {
            if(log.isErrorEnabled())
                log.error(this, e);
        }

        try {
          String createStmt = "CREATE DATABASE " + schema + " DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci";

          UpdateDBCommand.executeStmt(createStmt, conn);
        } catch (Exception e) {
            if(log.isErrorEnabled())
                log.error(this, e);
        }
        this.decorate(conn);

        CreateSchema createSchema = createSchema();
        if (createSchema != null) {
            createSchema.create();
        }
    }
}
